home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume3 / go / part04 < prev    next >
Encoding:
Text File  |  1988-03-09  |  50.1 KB  |  1,992 lines

  1. Path: uunet!husc6!bloom-beacon!mit-eddie!uw-beaver!tektronix!tekgen!tekred!games-request
  2. From: games-request@tekred.TEK.COM
  3. Newsgroups: comp.sources.games
  4. Subject: v03i100:  go - go board manager sources, Part04/05
  5. Message-ID: <2271@tekred.TEK.COM>
  6. Date: 9 Mar 88 17:57:46 GMT
  7. Sender: billr@tekred.TEK.COM
  8. Lines: 1981
  9. Approved: billr@tekred.TEK.COM
  10.  
  11. Submitted by: Fred Hansen <wjh+@andrew.cmu.edu>
  12. Comp.sources.games: Volume 3, Issue 100
  13. Archive-name: go/Part04
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 4 (of 5)."
  24. # Contents:  go.pas goMgr.pas
  25. # Wrapped by billr@saab on Wed Mar  9 09:14:46 1988
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f go.pas -a "${1}" != "-c" ; then 
  28.   echo shar: Will not over-write existing file \"go.pas\"
  29. else
  30. echo shar: Extracting \"go.pas\" \(26299 characters\)
  31. sed "s/^X//" >go.pas <<'END_OF_go.pas'
  32. X{---------------------------------------------------------------}
  33. X{ Go Game Manager                                               }
  34. X{ Copyright (c) 1982 by Three Rivers Computer Corp.             }
  35. X{                                                               }
  36. X{ Written: June 3, 1982 by Stoney Ballard                       }
  37. X{ Edit History:                                                 }
  38. X{    June  3, 1982 Started                                      }
  39. X{    June  4, 1982 Add dead group removal                       }
  40. X{    June 10, 1982 Use new go file manager                      }
  41. X{    Nov  10, 1982 Extensively Hacked Up                        }
  42. X{    Dec  29, 1982 Changed "Erase Branch" to "Prune Branches"   }
  43. X{    Jan   6, 1983 Added ^C escape from all readlns             }
  44. X{---------------------------------------------------------------}
  45. X
  46. Xprogram Go;
  47. X
  48. Xexports
  49. X
  50. Ximports stream from stream;
  51. X
  52. Xprocedure resetInput;
  53. X
  54. Xprivate
  55. X
  56. Ximports system from System;
  57. Ximports raster from raster;
  58. Ximports screen from screen;
  59. Ximports popUp from popUp;
  60. Ximports IO_Others from IO_Others;
  61. Ximports goCom from goCom;
  62. Ximports goMgr from goMgr;
  63. Ximports goTree from goTree;
  64. Ximports goBoard from goBoard;
  65. Ximports goMenu from goMenu; 
  66. Ximports memory from memory;
  67. Ximports perq_string from perq_string;
  68. Ximports goPlayer from goPlayer;
  69. X
  70. Xlabel
  71. X  99;       (* the fatal error point *)
  72. X
  73. Xvar
  74. X  oCurPosX, oCurPosY: integer;
  75. X  oScreenPtr: rasterPtr;
  76. X
  77. X  procedure resetInput;
  78. X  begin { resetInput }
  79. X    streamKeyboardReset(input);
  80. X  end { resetInput };
  81. X
  82. X  procedure newTitle;
  83. X  var
  84. X    ts: string[128];
  85. X    fn: string;
  86. X    fl, fPos, tPos, i: integer;
  87. X  begin { newTitle }
  88. X    ts := 'Go  Version ';
  89. X    ts := concat(ts, version);
  90. X    getFNameString(fn);
  91. X    fl := length(fn);
  92. X    if fl > 0 then
  93. X      begin
  94. X        fPos := 81 - fl;
  95. X        tPos := length(ts) + 1;
  96. X        adjust(ts, 80);
  97. X        for i := tPos to 80 do
  98. X          ts[i] := ' ';
  99. X        for i := fPos to fPos + fl - 1 do
  100. X          ts[i] := fn[i - fPos + 1];
  101. X      end;
  102. X    changeTitle(ts);
  103. X  end { newTitle };
  104. X
  105. X  procedure initialize;
  106. X  var
  107. X    sseg: integer;
  108. X
  109. X    procedure setupWindows;
  110. X    var
  111. X      ts: string;
  112. X    begin { setupWindows }
  113. X      createWindow(boardWin, bWinX, bWinY, bWinW, bWinH, ' ');
  114. X      createWindow(menuWin, mWinX, mWinY, mWinW, mWinH, '');
  115. X      createWindow(statWin, sWinX, sWinY, sWinW, sWinH, '');      
  116. X      changeWindow(0);
  117. X      gameFName := '';
  118. X      newTitle;
  119. X    end { setupWindows };
  120. X
  121. X  begin { initialize }
  122. X    createSegment(sseg, 192, 1, 192);
  123. X    oScreenPtr := makePtr(sseg, 0, rasterPtr);
  124. X    SReadCursor(oCurPosX, oCurPosY);
  125. X    rasterop(rRpl, 768, 1024, 0, 0, SScreenW, oScreenPtr,
  126. X                              0, 0, SScreenW, SScreenP);
  127. X    IOSetFunction(CTCursCompl);
  128. X    rasterop(RAndNot, 768, 1024, 0, 0, SScreenW, SScreenP,
  129. X                                 0, 0, SScreenW, SScreenP);
  130. X    setupWindows;
  131. X    initMenu;
  132. X    captures[black] := 0;
  133. X    captures[white] := 0;
  134. X    initGoTree;
  135. X    initGoBoard;
  136. X    makeGoTree;
  137. X    initGoMgr;
  138. X    gameFName := '';
  139. X    numbEnabled := false;
  140. X    treeDirty := false;
  141. X    playLevel := 0;
  142. X    debug := false;
  143. X    printLarge := true;
  144. X    initGoPlayer;
  145. X  end { initialize };
  146. X  
  147. X  procedure doit;
  148. X  var
  149. X    done, foundIt, endLoop, gbg: boolean;
  150. X    CtlCseen, playMyself, lastWasPass: boolean;
  151. X    whoseTurn, whoWasLast: sType;
  152. X    i, xi, yi, xs, ys: integer;
  153. X    numDead, numHC, cmd: integer;
  154. X    lastBuM: integer;
  155. X    thisTag: tagPtr;
  156. X    lastMove: pMRec;
  157. X
  158. X    function getLine(var l: string): boolean;
  159. X    label
  160. X      1;
  161. X    var
  162. X      i, j, cx, cy: integer;
  163. X
  164. X      handler ctlC;
  165. X      begin { ctlC }
  166. X        IOKeyClear;
  167. X        streamKeyboardReset(input);
  168. X        beep(error);
  169. X        prompt('');
  170. X        l := '';
  171. X        getLine := false;
  172. X        exit(getLine); 
  173. X      end { ctlC }; 
  174. X
  175. X      handler pastEOF(fn: pathName);
  176. X      begin { pastEOF }
  177. X        reset(input, fn);
  178. X        sSetCursor(cx, cy);
  179. X        write('    ');
  180. X        sSetCursor(cx, cy);
  181. X        goto 1;
  182. X      end { pastEOF };
  183. X
  184. X    begin { getLine }
  185. X      sReadCursor(cx, cy);
  186. X    1:
  187. X      readln(l);
  188. X      getLine := true;
  189. X      j := 0;
  190. X      for i := 1 to length(l) do
  191. X        if ord(l[i]) >= 32 then
  192. X          begin
  193. X            j := j + 1;
  194. X            l[j] := l[i];
  195. X          end;
  196. X      adjust(l, j);
  197. X    end { getLine };
  198. X
  199. X    procedure resetGame;
  200. X    begin { resetGame }
  201. X      clearBoard;
  202. X      koX := -1;
  203. X      koY := -1;
  204. X      moveNum := 0;
  205. X      curMove := treeRoot;
  206. X      captures[black] := 0;
  207. X      captures[white] := 0; 
  208. X      showCaptures;
  209. X      whoseTurn := black;
  210. X      turnIs(black);
  211. X      gameFname := '';
  212. X      newTitle;
  213. X      gameOver := false;
  214. X      initGoMgr;
  215. X    end { resetGame };
  216. X
  217. X    procedure switchWho;
  218. X    begin { switchWho }
  219. X      if curMove = treeRoot then
  220. X        whoseTurn := black
  221. X      else if curMove^.id = remove then
  222. X        whoseTurn := curMove^.who
  223. X      else if curMove^.id = hcPlay then
  224. X        whoseTurn := white
  225. X      else if curMove^.who = black then
  226. X        whoseTurn := white
  227. X      else
  228. X        whoseTurn := black;
  229. X      turnIs(whoseTurn);
  230. X    end { switchWho };
  231. X
  232. X    procedure updateStatus;
  233. X    begin { updateStatus }
  234. X      dotLast;
  235. X      showCaptures;
  236. X      showComment;
  237. X      showTag;
  238. X      switchWho;
  239. X    end { updateStatus };
  240. X
  241. X    procedure doReadGame;
  242. X    var
  243. X      fName: pathName;
  244. X
  245. X      handler badFileVersion;
  246. X      begin { badFileVersion }
  247. X        beep(error);
  248. X        prompt('');
  249. X        write(gameFName, ' is not compatable with this version of GO');
  250. X        resetGame;
  251. X        exit(doReadGame);
  252. X      end { badFileVersion };
  253. X
  254. X    begin { doReadGame }
  255. X      if menuGoFile(fName) then
  256. X        begin
  257. X          prompt('Reading ');
  258. X          write(fName, '.Go ...');
  259. X          readTree(concat(fName, '.GO'));
  260. X          resetGame;
  261. X          gameFName := fName;
  262. X          if treeRoot^.lastMove <> nil then
  263. X            switchBranch(treeRoot^.lastMove);
  264. X          treeDirty := false;
  265. X          prompt('');
  266. X          newTitle;
  267. X        end;
  268. X    end { doReadGame };
  269. X
  270. X    procedure doWriteGame;
  271. X    var
  272. X      fs: string;
  273. X      procedure addExt(var nam: string);
  274. X      var
  275. X        es: string;
  276. X      begin { addExt }
  277. X        if length(nam) > 3 then
  278. X          begin
  279. X            es := substr(nam, length(nam) - 2, 3);
  280. X            convUpper(es);
  281. X            if es <> '.GO' then
  282. X              nam := concat(nam, '.Go');
  283. X          end
  284. X        else
  285. X          nam := concat(nam, '.Go');
  286. X      end { addExt };
  287. X
  288. X      handler badGoWrite;
  289. X      begin { badGoWrite };
  290. X        beep(error);
  291. X        prompt('Unable to write file ');
  292. X        write(fs);
  293. X        exit(doWriteGame);
  294. X      end { badGoWrite };
  295. X
  296. X    begin { doWriteGame }
  297. X      IOKeyClear;
  298. X      streamKeyboardReset(input);
  299. X      if gameFName <> '' then
  300. X        begin
  301. X          prompt('Game File Name [');
  302. X          write(gameFName, ']? ');
  303. X        end
  304. X      else
  305. X        prompt('Game File Name? ');
  306. X      if not getLine(fs) then
  307. X        exit(doWriteGame);
  308. X      if fs = '' then
  309. X        if gameFName = '' then
  310. X          begin
  311. X            beep(error);
  312. X            prompt('');
  313. X            exit(doWriteGame);
  314. X          end
  315. X        else
  316. X          fs := gameFName;
  317. X      gameFName := fs;
  318. X      addExt(fs);
  319. X      prompt('Writing ');
  320. X      write(fs, ' ...');
  321. X      writeTree(fs, curMove);
  322. X      treeDirty := false;
  323. X      prompt('');
  324. X      newTitle;
  325. X    end { doWriteGame };
  326. X
  327. X    function chooseAlt: boolean;
  328. X    label
  329. X      10;
  330. X    var
  331. X      bx, by, xs, ys: integer;
  332. X      tm: pMRec;
  333. X      hc0There: boolean;
  334. X      hcMenu: pNameDesc;
  335. X      res: resres;
  336. X      numHC, i, j, numNHC: integer;
  337. X
  338. X      handler outside;
  339. X      begin { outside }
  340. X        destroyNameDesc(hcMenu);
  341. X        chooseAlt := false;
  342. X        beep(error);
  343. X        restoreCursor;
  344. X        exit(chooseAlt);
  345. X      end { outside };
  346. X
  347. X    begin { chooseAlt }
  348. X      chooseAlt := false;
  349. X      switchWho;
  350. X      waitNoButton;
  351. X      tm := curMove^.flink;
  352. X      numHC := 0;
  353. X      numNHC := 0;
  354. X      hc0There := false;
  355. X      while tm <> nil do
  356. X        begin
  357. X          if tm^.id = hcPlay then
  358. X            numHC := numHC + 1
  359. X          else
  360. X            begin
  361. X              hc0There := true;
  362. X              numNHC := numNHC + 1;
  363. X            end;
  364. X          tm := tm^.slink;
  365. X        end;
  366. X      if numHC > 0 then
  367. X        begin
  368. X          if hc0There then
  369. X            numHC := numHC + 1;
  370. X          allocNameDesc(numHC, 0, hcMenu);
  371. X          hcMenu^.header := 'Handicap Alternates';
  372. X          j := 1;
  373. X          if hc0There then
  374. X            begin
  375. X              hcMenu^.commands[1] := '0';
  376. X              j := 2;
  377. X            end;
  378. X          tm := curMove^.flink;
  379. X          for i := j to numHC do
  380. X            begin
  381. X              while tm^.id <> hcPlay do
  382. X                tm := tm^.slink;
  383. X    {$R-}
  384. X              hcMenu^.commands[i] := ' ';
  385. X              hcMenu^.commands[i][1] := chr(tm^.hcNum + ord('0'));
  386. X    {$R=}
  387. X              tm := tm^.slink;
  388. X            end;
  389. X          menu(hcMenu, false, 1, numHC, -1, -1, -1, res);
  390. X          restoreCursor;
  391. X          destroyNameDesc(hcMenu);
  392. X          i := res^.indices[1];
  393. X          destroyRes(res);
  394. X          if hc0There then
  395. X            if i = 1 then
  396. X              begin
  397. X                if numNHC > 1 then
  398. X                  goto 10;
  399. X                tm := curMove^.flink;
  400. X                while tm^.id <> move do
  401. X                  tm := tm^.slink;
  402. X                forwardTo(tm);
  403. X                chooseAlt := true;
  404. X                exit(chooseAlt);
  405. X              end
  406. X            else
  407. X              i := i - 1;
  408. X          tm := curMove^.flink;
  409. X          j := 0;
  410. X          repeat
  411. X            while tm^.id <> hcPlay do
  412. X              tm := tm^.slink;
  413. X            j := j + 1;
  414. X            if j <> i then
  415. X              tm := tm^.slink;
  416. X          until j = i;
  417. X          forwardTo(tm);
  418. X          chooseAlt := true;
  419. X        end
  420. X      else
  421. X        begin
  422. X  10:
  423. X          showAlts;
  424. X          waitButton;
  425. X          if passLocCur(tabRelX, tabRelY) then
  426. X            begin
  427. X              if passIsAlt then
  428. X                begin
  429. X                  selPass;
  430. X                  chooseAlt := true;
  431. X                  waitNoButton;
  432. X                  exit(chooseAlt);
  433. X                end;
  434. X            end
  435. X          else if bLocCur(tabRelX, tabRelY, bx, by, xs, ys) then
  436. X            if board[bx][by].val = alternate then
  437. X              begin
  438. X                selAlt(bx, by);
  439. X                chooseAlt := true;
  440. X                waitNoButton;
  441. X                exit(chooseAlt);
  442. X              end;
  443. X          remAlts;
  444. X          beep(error);
  445. X        end;
  446. X      waitNoButton;
  447. X    end { chooseAlt };
  448. X
  449. X    procedure mForward;
  450. X    var
  451. X      gbg: boolean;
  452. X    begin { mForward }
  453. X      if gameOver then
  454. X        restoreDead;
  455. X      if atLeaf(curMove) then
  456. X        beep(error)
  457. X      else if atBranch(curMove) then
  458. X        gbg := chooseAlt
  459. X      else
  460. X        forwardTo(curMove^.flink);
  461. X    end { mForward };
  462. X
  463. X    procedure doBkToS;
  464. X    var
  465. X      bx, by, sx, sy: integer;
  466. X    begin { doBkToS }
  467. X      prompt('Point at stone to backup to');
  468. X      waitButton;
  469. X      if bLocCur(tabRelX, tabRelY, bx, by, xs, ys) then
  470. X        if board[bx][by].val <> empty then
  471. X          begin
  472. X            while not lastPlayAt(bx, by) do
  473. X              backup1;
  474. X            exit(doBkToS);
  475. X          end;
  476. X      beep(error);
  477. X      waitNoButton;
  478. X    end { doBkToS };
  479. X
  480. X    procedure doPutTag;
  481. X    var
  482. X      ts: tagStr;
  483. X      cm: pMRec;
  484. X    begin { doPutTag }
  485. X      if curMove = treeRoot then
  486. X        beep(error)
  487. X      else
  488. X        begin
  489. X          IOKeyClear;
  490. X          streamKeyboardReset(input);
  491. X          prompt('Tag String: ');
  492. X          if not getLine(ts) then
  493. X            exit(doPutTag);
  494. X          if length(ts) > maxTagLen then
  495. X            begin
  496. X              beep(error);
  497. X              prompt('Tags may be no longer than ');
  498. X              write(maxTagLen:0, ' characters');
  499. X            end
  500. X          else if length(ts) = 0 then
  501. X            begin
  502. X              if curMove^.tag = nil then
  503. X                begin
  504. X                  beep(error);
  505. X                  prompt('');
  506. X                end
  507. X              else
  508. X                begin
  509. X                  delTag(curMove^.tag);
  510. X                  prompt('Tag Deleted');
  511. X                end;
  512. X            end
  513. X          else if tagExists(ts) then
  514. X            begin
  515. X              beep(error);
  516. X              prompt('That tag already exists');
  517. X            end
  518. X          else
  519. X            begin
  520. X              tagMove(curMove, ts);
  521. X            end;
  522. X        end;
  523. X    end { doPutTag };
  524. X
  525. X    procedure doGoToTag;
  526. X    var
  527. X      thisTag: tagPtr;
  528. X    begin { doGoToTag }
  529. X      thisTag := getTagMenu;
  530. X      if thisTag <> nil then  
  531. X        switchBranch(thisTag^.mPtr);
  532. X    end { doGoToTag };
  533. X
  534. X    procedure doPutCmt;
  535. X    var
  536. X      cs, curCmt: string;
  537. X    begin { doPutCmt }
  538. X      IOKeyClear;
  539. X      streamKeyboardReset(input);
  540. X      prompt('Comment: ');
  541. X      if not getLine(cs) then
  542. X        exit(doPutCmt);
  543. X      if length(cs) = 0 then
  544. X        if getComment(curMove, curCmt) then
  545. X          prompt('Comment Deleted')
  546. X        else
  547. X          begin
  548. X            beep(error);
  549. X            prompt('');
  550. X          end;
  551. X      commentMove(curMove, cs);
  552. X    end { doPutCmt };
  553. X
  554. X    procedure doScore;
  555. X    var
  556. X      wScore, bScore, wr, br: integer;
  557. X      done: boolean;
  558. X      bx, by, xs, ys: integer;
  559. X    begin { doScore }
  560. X      putEnd;
  561. X      done := false;
  562. X      prompt('Point at dead groups, Press outside of board to stop');
  563. X      repeat
  564. X        waitButton;
  565. X        if bLocCur(tabRelX, tabRelY, bx, by, xs, ys) then
  566. X          begin
  567. X            if board[bx, by].val <> empty then
  568. X              delGroup(bx, by);
  569. X          end
  570. X        else
  571. X          done := true;
  572. X        showCaptures;
  573. X        waitNoButton;
  574. X      until done;
  575. X      prompt('Counting Score ...');
  576. X      scoreGame(wScore, bScore);
  577. X      wScore := wScore - captures[black];
  578. X      bScore := bScore - captures[white];
  579. X      if wScore < 0 then
  580. X        begin
  581. X          wr := -wScore;
  582. X          wScore := 0;
  583. X        end
  584. X      else
  585. X        wr := 0;
  586. X      if bScore < 0 then
  587. X        begin
  588. X          br := -bScore;
  589. X          bScore := 0;
  590. X        end
  591. X      else
  592. X        br := 0;
  593. X      bScore := bScore + wr;
  594. X      wScore := wScore + br;
  595. X      prompt('Score is: ');
  596. X      write('White = ', wScore:0, ', Black = ', bScore:0);
  597. X      if wScore = bScore then
  598. X        write(' - A Tie!')
  599. X      else if wScore > bScore then
  600. X        write(' - White Wins by ', (wScore - bScore):0)
  601. X      else
  602. X        write(' - Black Wins by ', (bScore - wScore):0)
  603. X    end { doScore };
  604. X
  605. X    procedure doEraseMove;
  606. X    var
  607. X      lm: pMRec;
  608. X    begin { doEraseMove }
  609. X      if gameOver then
  610. X        restoreDead;
  611. X      if curMove = treeRoot then
  612. X        beep(error)
  613. X      else
  614. X        begin
  615. X          lm := curMove;
  616. X          backup1;
  617. X          lm := delBranch(lm);
  618. X          treeDirty := true;
  619. X        end;
  620. X    end { doEraseMove };
  621. X
  622. X    procedure doPruneBranches;
  623. X    var
  624. X      lm, sm, tm: pMRec;
  625. X      tp: tagPtr;
  626. X      didPrune: boolean;
  627. X    begin { doPruneBranches }
  628. X      if gameOver then
  629. X        restoreDead;
  630. X      if not isBranch(curMove) then
  631. X        beep(error)
  632. X      else if not confirmed then
  633. X        beep(error)
  634. X      else
  635. X        begin
  636. X          didPrune := false;
  637. X          wipeTreeMarks;
  638. X          lm := curMove;
  639. X          while lm <> treeRoot do
  640. X            begin
  641. X              lm^.mark := true;
  642. X              lm := lm^.blink;
  643. X            end;
  644. X          tp := treeRoot^.lastTag;
  645. X          while tp <> nil do
  646. X            begin
  647. X              lm := tp^.mPtr;
  648. X              while lm <> treeRoot do
  649. X                begin
  650. X                  lm^.mark := true;
  651. X                  lm := lm^.blink;
  652. X                end;
  653. X              tp := tp^.nextTag;
  654. X            end;
  655. X          lm := curMove;
  656. X          while lm <> treeRoot do
  657. X            begin
  658. X              if lm^.blink^.flink^.slink <> nil then
  659. X                begin
  660. X                  sm := lm^.blink^.flink;
  661. X                  while sm <> nil do
  662. X                    if not sm^.mark then
  663. X                      begin
  664. X                        tm := sm;
  665. X                        sm := sm^.slink;
  666. X                        tm := delBranch(tm);
  667. X                        didPrune := true;
  668. X                        treeDirty := true;
  669. X                      end
  670. X                    else
  671. X                      sm := sm^.slink;
  672. X                end;
  673. X              lm := lm^.blink;
  674. X            end;
  675. X          if not didPrune then
  676. X            prompt('All Branches Were Tagged');
  677. X        end;
  678. X    end { doPruneBranches };
  679. X
  680. X    handler ctlC;
  681. X    begin { ctlC }
  682. X      IOKeyClear;
  683. X      CtlCseen := true;
  684. X    end { ctlC }; 
  685. X
  686. X  begin { doit }
  687. X    resetGame;
  688. X    done := false;
  689. X    lastMove := nil;
  690. X    CtlCseen := false;
  691. X    playMyself := false;
  692. X    lastWasPass := false;
  693. X    IOSetModeTablet(relTablet);
  694. X    IOCursorMode(trackCursor);
  695. X    activate(mReadFile, true);
  696. X    activate(mTogNums, true);
  697. X    activate(mQuit, true);
  698. X    activate(mPutCmt, true);
  699. X    activate(mAutoPlay, true);
  700. X    activate(mPlayMyself, true);
  701. X    activate(mSetPlayLevel, true);
  702. X    activate(mDebug, true);
  703. X    activate(mRefBoard, true);
  704. X    activate(mShoState, true);
  705. X    activate(mBoardSize, true);
  706. X    repeat
  707. X      if curMove <> lastMove then
  708. X        checkAtari(curMove);
  709. X      updateStatus;
  710. X      lastMove := curMove;
  711. X      if not playMyself then
  712. X        begin
  713. X          activate(mPrintBoard, curMove <> treeRoot);
  714. X          activate(mPrintDiag, curMove <> treeRoot);
  715. X          activate(mStepToTag, stepTagPossible);
  716. X          activate(mSetStepTag, treeRoot^.lastTag <> nil);
  717. X          activate(mGotoTag, treeRoot^.lastTag <> nil);
  718. X          activate(mInit, treeRoot^.flink <> nil);
  719. X          activate(mWriteFile, treeRoot^.flink <> nil);
  720. X          activate(mSetHc, curMove = treeRoot);
  721. X          activate(mPass, curMove <> treeRoot);
  722. X          activate(mScore, curMove <> treeRoot);
  723. X          activate(mForToBr, hasBranch(curMove));
  724. X          activate(mBackToBr, isBranch(curMove));
  725. X          activate(mBackToStone, curMove <> treeRoot);
  726. X          activate(mForToLeaf, curMove^.flink <> nil);
  727. X          activate(mPutTag, curMove <> treeRoot);
  728. X          activate(mGotoRoot, curMove <> treeRoot);
  729. X          activate(mEraseMove, curMove <> treeRoot);
  730. X          activate(mPruneBranches, isBranch(curMove));
  731. X          activate(mBackOne, curMove <> treeRoot);
  732. X          activate(mForOne, curMove^.flink <> nil);
  733. X        end;
  734. X      if CtlCseen then
  735. X        cmd := mCtlC
  736. X      else if playMyself then
  737. X        cmd := mAutoPlay
  738. X      else
  739. X        repeat
  740. X          cmd := getMenuCmd;
  741. X        until cmd <> none;
  742. X      prompt('');
  743. X      case cmd of
  744. X        mCtlC:
  745. X          begin
  746. X            playMyself := false;
  747. X            CtlCseen := false;
  748. X          end;
  749. X        mPlaceStone:
  750. X          begin
  751. X            if gameOver then
  752. X              restoreDead;
  753. X            if bLocCur(tabRelX, tabRelY, xi, yi, xs, ys) then
  754. X              begin
  755. X                if board[xi, yi].val <> empty then
  756. X                  beep(error)
  757. X                else if (xi = koX) and (yi = koY) then
  758. X                  beep(koV)
  759. X                else
  760. X                  doMove(whoseTurn, xi, yi, xs, ys);
  761. X              end
  762. X            else
  763. X              beep(error);
  764. X            waitNoButton;
  765. X          end;
  766. X        mAutoPlay:
  767. X          begin
  768. X            if gameOver then
  769. X              restoreDead;
  770. X            prompt('Thinking...');
  771. X            if curMove = treeRoot then
  772. X              lastWasPass := false
  773. X            else
  774. X              lastWasPass := curMove^.id = pass;
  775. X            if playMove(whoseTurn, xi, yi) then
  776. X              begin
  777. X                if board[xi, yi].val <> empty then
  778. X                  begin
  779. X                    beep(error);
  780. X                    prompt('Bad move at ');
  781. X                    write((xi + 1):0, ', ', (yi + 1):0);
  782. X                    playMyself := false;
  783. X                    write(' - Generated by ', playreason);
  784. X                  end
  785. X                else if (xi = koX) and (yi = koY) then
  786. X                  begin
  787. X                    beep(koV);
  788. X                    prompt('ko violation at ');
  789. X                    write((xi + 1):0, ', ', (yi + 1):0);
  790. X                    write(' - Generated by ', playreason);
  791. X                    playMyself := false;
  792. X                  end
  793. X                else
  794. X                  begin
  795. X                    doMove(whoseTurn, xi, yi, 0, 0);
  796. X                    if board[xi, yi].val = empty then
  797. X                      begin
  798. X                        prompt('self kill at ');
  799. X                        write((xi + 1):0, ', ', (yi + 1):0);
  800. X                        write(' - Generated by ', playreason);
  801. X                        playMyself := false;
  802. X                      end
  803. X                    else
  804. X                      commentMove(curMove, playReason);
  805. X                  end;
  806. X              end
  807. X            else
  808. X              begin
  809. X                doPass(whoseTurn);
  810. X                if lastWasPass then
  811. X                  playMyself := false;
  812. X              end;
  813. X            waitNoButton;
  814. X            prompt('');
  815. X          end;
  816. X        mPlayMyself:
  817. X          playMyself := true;
  818. X        mSetPlayLevel:
  819. X          menuPlayLevel(playLevel, maxPlayLevel);
  820. X        mShoState:
  821. X          showPlayState(whoseTurn);
  822. X        mInit:
  823. X          if confirmed then
  824. X            begin
  825. X              makeGoTree;
  826. X              resetGame;
  827. X              treeDirty := false;
  828. X            end
  829. X          else
  830. X            beep(error);
  831. X        mSetHc:
  832. X          if moveNum = 0 then
  833. X            begin
  834. X              if gameOver then
  835. X                restoreDead;
  836. X              numHC := getHCMenu;
  837. X              if numHC > 0 then
  838. X                doHCPlay(numHC)
  839. X              else
  840. X                beep(error);
  841. X            end
  842. X          else
  843. X            beep(error);
  844. X        mPass:
  845. X          begin
  846. X            if gameOver then
  847. X              restoreDead;
  848. X            doPass(whoseTurn);
  849. X          end;
  850. X        mScore:
  851. X          doScore;
  852. X        mForToBr:
  853. X          begin
  854. X            if gameOver then
  855. X              restoreDead;
  856. X            if atLeaf(curMove) then
  857. X              beep(error)
  858. X            else if not atBranch(curMove) then
  859. X               forwToBr;
  860. X            if not atLeaf(curMove) then
  861. X              gbg := chooseAlt;
  862. X          end;
  863. X        mBackToBr:
  864. X          begin
  865. X            if gameOver then
  866. X              restoreDead;
  867. X            if curMove = treeRoot then
  868. X              beep(error)
  869. X            else
  870. X              backToBr;
  871. X            if atBranch(curMove) then
  872. X              gbg := chooseAlt;
  873. X          end;
  874. X        mBackToStone:
  875. X          begin
  876. X            if gameOver then
  877. X              restoreDead;
  878. X            if curMove = treeRoot then
  879. X              beep(error)
  880. X            else
  881. X              doBkToS;
  882. X          end;
  883. X        mForToLeaf:
  884. X          begin
  885. X            if gameOver then
  886. X              restoreDead;
  887. X            if atLeaf(curMove) then
  888. X              beep(error)
  889. X            else
  890. X              begin
  891. X                endLoop := false;
  892. X                repeat
  893. X                  if atLeaf(curMove) then
  894. X                    endLoop := true
  895. X                  else if atBranch(curMove) then
  896. X                    begin
  897. X                      if not chooseAlt then
  898. X                        begin
  899. X                          endLoop := true;
  900. X                          beep(error);
  901. X                        end;
  902. X                    end
  903. X                  else
  904. X                    forwToBr;                    
  905. X                until endLoop;
  906. X              end;
  907. X          end;
  908. X        mPutTag:
  909. X          doPutTag;
  910. X        mGotoTag:
  911. X          doGoToTag;
  912. X        mGotoRoot:
  913. X          switchBranch(treeRoot);
  914. X        mPutCmt:
  915. X          doPutCmt;
  916. X        mReadFile:
  917. X          if confirmed then
  918. X            doReadGame;
  919. X        mWriteFile:
  920. X          doWriteGame;
  921. X        mEraseMove:
  922. X          doEraseMove;
  923. X        mPruneBranches:
  924. X          doPruneBranches;
  925. X        mTogNums:
  926. X          if not numbEnabled then
  927. X            begin
  928. X              numbEnabled := true;
  929. X              showAllStones;
  930. X              dotSX := -1;
  931. X              putMString(mTogNums, 'Erase Numbers');
  932. X            end
  933. X          else
  934. X            begin
  935. X              numbEnabled := false;
  936. X              showAllStones;
  937. X              dotSX := -1;
  938. X              dotLast;
  939. X              putMString(mTogNums, 'Show Stone Numbers');
  940. X            end;
  941. X        mDebug:
  942. X          if debug then
  943. X            begin
  944. X              debug := false;
  945. X              putMString(mDebug, 'Turn Debug On');
  946. X            end
  947. X          else
  948. X            begin
  949. X              debug := true;
  950. X              putMString(mDebug, 'Turn Debug Off');
  951. X            end;
  952. X        mBoardSize:
  953. X          begin
  954. X            printLarge := not printLarge;
  955. X            if printLarge then
  956. X              begin
  957. X                prompt('Will Print on Large Board Now');
  958. X                putMString(mBoardSize, 'Use Small Board');
  959. X              end
  960. X            else
  961. X              begin
  962. X                prompt('Will Print on Small Board Now');
  963. X                putMString(mBoardSize, 'Use Large Board');
  964. X              end;
  965. X          end;
  966. X        mPrintBoard:
  967. X          printBoard(false);
  968. X        mPrintDiag:
  969. X          printBoard(true);
  970. X        mStepToTag:
  971. X          begin
  972. X            if gameOver then
  973. X              restoreDead;
  974. X            if stepTag = nil then
  975. X              stepTag := getTagMenu;
  976. X            if stepTag <> nil then
  977. X              doStepTag
  978. X            else
  979. X              beep(error);
  980. X          end;
  981. X        mSetStepTag:
  982. X          begin
  983. X            thisTag := getTagMenu;
  984. X            if thisTag <> nil then
  985. X              stepTag := thisTag;
  986. X          end;
  987. X        mQuit:
  988. X          if confirmed then
  989. X            done := true;
  990. X        mBackOne:
  991. X          begin
  992. X            if gameOver then
  993. X              restoreDead
  994. X            else if curMove = treeRoot then
  995. X              beep(error)
  996. X            else
  997. X              backUp1;
  998. X          end;
  999. X        mForOne:
  1000. X          begin
  1001. X            if gameOver then
  1002. X              restoreDead;
  1003. X            mForward;
  1004. X          end;
  1005. X        mRefBoard:
  1006. X          refreshBoard;
  1007. X      end { case };
  1008. X      if not playMyself then
  1009. X        endCmd;
  1010. X    until done;
  1011. X  end { doit };
  1012. X
  1013. X  procedure cleanup;
  1014. X  begin { cleanup }
  1015. X    screenReset;
  1016. X    rasterOp(rRpl, 768, 1024, 0, 0, SScreenW, SScreenP,
  1017. X                              0, 0, SScreenW, oScreenPtr);
  1018. X    SSetCursor(oCurPosX, oCurPosY);
  1019. X  end { cleanup };
  1020. X
  1021. X  handler ctlC;
  1022. X  begin { ctlC }
  1023. X    IOKeyClear; 
  1024. X  end { ctlC };
  1025. Xbegin { Go } 
  1026. X  initialize;
  1027. X  doit;
  1028. X99:
  1029. X  cleanUp;
  1030. Xend { Go }.
  1031. END_OF_go.pas
  1032. if test 26299 -ne `wc -c <go.pas`; then
  1033.     echo shar: \"go.pas\" unpacked with wrong size!
  1034. fi
  1035. # end of overwriting check
  1036. fi
  1037. if test -f goMgr.pas -a "${1}" != "-c" ; then 
  1038.   echo shar: Will not over-write existing file \"goMgr.pas\"
  1039. else
  1040. echo shar: Extracting \"goMgr.pas\" \(20985 characters\)
  1041. sed "s/^X//" >goMgr.pas <<'END_OF_goMgr.pas'
  1042. X{---------------------------------------------------------------}
  1043. X{ GoMgr.Pas                                                     }
  1044. X{                                                               }
  1045. X{ Go Game Manager                                               }
  1046. X{ Copyright (c) 1982 by Three Rivers Computer Corp.             }
  1047. X{                                                               }
  1048. X{ Written: June 3, 1982 by Stoney Ballard                       }
  1049. X{ Edit History:                                                 }
  1050. X{    June  3, 1982  Started                                     }
  1051. X{    June  4, 1982  Add dead group removal                      }
  1052. X{    June 10, 1982  Use new go file manager                     }
  1053. X{    Nov   9, 1982  Extracted from GO.PAS                       }
  1054. X{---------------------------------------------------------------}
  1055. X
  1056. Xmodule goMgr;
  1057. X
  1058. Xexports
  1059. X
  1060. Ximports goCom from goCom;
  1061. Ximports goTree from goTree;
  1062. X
  1063. Xvar
  1064. X  curMove: pMRec;
  1065. X  gameOver: boolean;
  1066. X  passIsAlt: boolean;
  1067. X
  1068. Xprocedure initGoMgr;
  1069. Xprocedure backUp1;
  1070. Xprocedure doMove(which: sType; ix, iy, pox, poy: integer);
  1071. Xprocedure doPass(which: sType);
  1072. Xprocedure doHCPlay(num: integer);
  1073. Xprocedure forwardTo(m: pMRec);
  1074. Xprocedure forwToBr;
  1075. Xprocedure backToBr;
  1076. Xprocedure showAlts;
  1077. Xprocedure remAlts;
  1078. Xprocedure selAlt(lx, ly: integer);
  1079. Xprocedure selPass;
  1080. Xfunction atBranch(cm: pMRec): boolean;
  1081. Xfunction atLeaf(cm: pMRec): boolean;
  1082. Xprocedure checkAtari(cm: pMRec);
  1083. Xprocedure switchBranch(bm: pMRec);
  1084. Xprocedure scoreGame(var ws, bs: integer);
  1085. Xprocedure putEnd;
  1086. Xprocedure delGroup(bx, by: integer);
  1087. Xprocedure restoreDead;
  1088. Xprocedure dotLast;
  1089. Xfunction lastPlayAt(bx, by: integer): boolean;
  1090. Xprocedure doStepTag;
  1091. Xfunction stepTagPossible: boolean;
  1092. Xprocedure wipeTreeMarks;
  1093. X
  1094. Xprivate
  1095. X
  1096. Ximports goBoard from goBoard;
  1097. Ximports goMenu from goMenu;
  1098. Ximports screen from screen;
  1099. X
  1100. Xtype
  1101. X  deadRec = record
  1102. X              dx, dy, dox, doy, mn: integer;
  1103. X              whoDead: sType;
  1104. X            end;
  1105. X
  1106. Xvar
  1107. X  killX, killY: integer;
  1108. X  endDead: array[1..361] of deadRec;
  1109. X  numEndDead: integer;
  1110. X
  1111. Xprocedure wipeMarks;
  1112. Xvar
  1113. X  i, j: integer;
  1114. Xbegin { wipeMarks }
  1115. X  for i := 0 to maxPoint do
  1116. X    for j := 0 to maxPoint do
  1117. X      board[i, j].marked := false;
  1118. Xend { wipeMarks };
  1119. X
  1120. Xprocedure wipeTreeMarks;
  1121. X
  1122. X  procedure recWipe(m: pMRec);
  1123. X  begin { recWipe }
  1124. X    while m <> nil do
  1125. X      begin
  1126. X        recWipe(m^.slink);
  1127. X        m^.mark := false;
  1128. X        m := m^.flink;
  1129. X      end;
  1130. X  end { recWipe };
  1131. X
  1132. Xbegin { wipeTreeMarks }
  1133. X  treeRoot^.mark := false;
  1134. X  if treeRoot^.flink <> nil then
  1135. X    recWipe(treeRoot^.flink);
  1136. Xend { wipeTreeMarks };
  1137. X
  1138. Xprocedure spanGroup(s: sType; xi, yi: integer; var libs, size: integer);
  1139. Xbegin { spanGroup }
  1140. X  if (xi >= 0) and (xi <= maxPoint) and
  1141. X     (yi >= 0) and (yi <= maxPoint) then
  1142. X    with board[xi, yi] do
  1143. X      if not marked then
  1144. X        if val = empty then
  1145. X          begin
  1146. X            libs := libs + 1;
  1147. X            marked := true;
  1148. X          end
  1149. X        else if val = s then
  1150. X          begin
  1151. X            marked := true;
  1152. X            size := size + 1;
  1153. X            spanGroup(s, xi - 1, yi, libs, size);
  1154. X            spanGroup(s, xi + 1, yi, libs, size);
  1155. X            spanGroup(s, xi, yi - 1, libs, size);
  1156. X            spanGroup(s, xi, yi + 1, libs, size);
  1157. X          end;
  1158. Xend { spanGroup };
  1159. X
  1160. Xfunction libertyCount(xi, yi: integer): integer;
  1161. Xvar
  1162. X  libs, size: integer;
  1163. Xbegin { libertyCount }
  1164. X  wipeMarks;
  1165. X  libs := 0; 
  1166. X  size := 0;
  1167. X  spanGroup(board[xi, yi].val, xi, yi, libs, size);
  1168. X  libertyCount := libs;
  1169. Xend { libertyCount };
  1170. X
  1171. Xfunction groupSize(xi, yi: integer): integer;
  1172. Xvar
  1173. X  gbg, size: integer;
  1174. Xbegin { groupSize }
  1175. X  wipeMarks;
  1176. X  size := 0;
  1177. X  gbg := 0;
  1178. X  spanGroup(board[xi, yi].val, xi, yi, gbg, size); 
  1179. X  groupSize := size;
  1180. Xend { groupSize };
  1181. X
  1182. Xprocedure killGroup(s: sType; xi, yi: integer);
  1183. Xbegin { killGroup }
  1184. X  if (xi >= 0) and (xi <= maxPoint) and
  1185. X     (yi >= 0) and (yi <= maxPoint) then
  1186. X    with board[xi, yi] do
  1187. X      if val = s then
  1188. X        begin
  1189. X          remStone(xi, yi);
  1190. X          curMove := newMove(curMove);
  1191. X          with curMove^ do
  1192. X            begin
  1193. X              mx := xi;
  1194. X              my := yi;
  1195. X              ox := board[xi, yi].xOfs;
  1196. X              oy := board[xi, yi].yOfs;
  1197. X              moveN := board[xi, yi].mNum;
  1198. X              who := s;
  1199. X              id := remove;
  1200. X            end;
  1201. X          curMove := mergeMove(curMove);
  1202. X          killGroup(s, xi - 1, yi);
  1203. X          killGroup(s, xi + 1, yi);
  1204. X          killGroup(s, xi, yi - 1);
  1205. X          killGroup(s, xi, yi + 1);
  1206. X        end;
  1207. Xend { killGroup };
  1208. X
  1209. Xprocedure remDead(xi, yi: integer; var numDead: integer);
  1210. Xvar
  1211. X  i, j, libs, size: integer;
  1212. X  s, other: bVal;
  1213. X
  1214. Xbegin { remDead }
  1215. X  numDead := 0;
  1216. X  s := board[xi, yi].val;
  1217. X  if s = white then
  1218. X    other := black
  1219. X  else
  1220. X    other := white;
  1221. X  if xi > 0 then
  1222. X    if (board[xi - 1, yi].val = other) then
  1223. X      begin
  1224. X        wipeMarks;
  1225. X        libs := 0;
  1226. X        size := 0;
  1227. X        spanGroup(other, xi - 1, yi, libs, size);
  1228. X        if libs = 0 then
  1229. X          begin
  1230. X            killGroup(other, xi - 1, yi);
  1231. X            numDead := numDead + size;
  1232. X            killX := xi - 1;
  1233. X            killY := yi;
  1234. X          end;
  1235. X      end;
  1236. X  if xi < maxPoint then
  1237. X    if (board[xi + 1, yi].val = other) then
  1238. X      begin
  1239. X        wipeMarks;
  1240. X        libs := 0;
  1241. X        size := 0;
  1242. X        spanGroup(other, xi + 1, yi, libs, size);
  1243. X        if libs = 0 then
  1244. X          begin
  1245. X            killGroup(other, xi + 1, yi);
  1246. X            numDead := numDead + size;
  1247. X            killX := xi + 1;
  1248. X            killY := yi;
  1249. X          end;
  1250. X      end;
  1251. X  if yi > 0 then 
  1252. X    if (board[xi, yi - 1].val = other) then
  1253. X      begin
  1254. X        wipeMarks;
  1255. X        libs := 0;
  1256. X        size := 0;
  1257. X        spanGroup(other, xi, yi - 1, libs, size);
  1258. X        if libs = 0 then
  1259. X          begin
  1260. X            killGroup(other, xi, yi - 1);
  1261. X            numDead := numDead + size;
  1262. X            killX := xi;
  1263. X            killY := yi - 1;
  1264. X          end;
  1265. X      end;
  1266. X  if yi < maxPoint then
  1267. X    if (board[xi, yi + 1].val = other) then
  1268. X      begin
  1269. X        wipeMarks;
  1270. X        libs := 0;
  1271. X        size := 0;
  1272. X        spanGroup(other, xi, yi + 1, libs, size);
  1273. X        if libs = 0 then
  1274. X          begin
  1275. X            killGroup(other, xi, yi + 1);
  1276. X            numDead := numDead + size;
  1277. X            killX := xi;
  1278. X            killY := yi + 1;
  1279. X          end;
  1280. X      end;
  1281. X  if numDead > 0 then
  1282. X    beep(die);
  1283. Xend { remDead };
  1284. X
  1285. Xfunction lastPlayAt(bx, by: integer): boolean;
  1286. Xvar
  1287. X  tm: pMRec;
  1288. Xbegin { lastPlayAt }
  1289. X  lastPlayAt := false;
  1290. X  tm := curMove;
  1291. X  while tm <> treeRoot do
  1292. X    with tm^ do
  1293. X      if id = move then
  1294. X        begin
  1295. X          lastPlayAt := (mx = bx) and (my = by);
  1296. X          exit(lastPlayAt);
  1297. X        end
  1298. X      else if id = pass then
  1299. X        exit(lastPlayAt)
  1300. X      else if id = hcPlay then
  1301. X        exit(lastPlayAt)
  1302. X      else
  1303. X        tm := tm^.blink;
  1304. Xend { lastPlayAt };
  1305. X
  1306. Xprocedure findAtari(xi, yi: integer);
  1307. Xvar
  1308. X  i, j, libs, num, size: integer;
  1309. X  s, other: bVal;
  1310. Xbegin { findAtari }
  1311. X  size := 0;
  1312. X  s := board[xi, yi].val;
  1313. X  if s = white then
  1314. X    other := black
  1315. X  else
  1316. X    other := white;
  1317. X  wipeMarks;
  1318. X  libs := 0;
  1319. X  spanGroup(s, xi, yi, libs, size);
  1320. X  if libs = 1 then
  1321. X    begin
  1322. X      beep(atari);
  1323. X      exit(findAtari);
  1324. X    end;
  1325. X  if xi > 0 then
  1326. X    if (board[xi - 1, yi].val = other) and
  1327. X       (not board[xi - 1, yi].marked) then
  1328. X      begin
  1329. X        wipeMarks;
  1330. X        libs := 0;
  1331. X        spanGroup(other, xi - 1, yi, libs, size);
  1332. X        if libs = 1 then
  1333. X          begin
  1334. X            beep(atari);
  1335. X            exit(findAtari);
  1336. X          end;
  1337. X      end;
  1338. X  if xi < maxPoint then
  1339. X    if (board[xi + 1, yi].val = other) and
  1340. X       (not board[xi + 1, yi].marked) then
  1341. X      begin
  1342. X        wipeMarks;
  1343. X        libs := 0;
  1344. X        spanGroup(other, xi + 1, yi, libs, size);
  1345. X        if libs = 1 then
  1346. X          begin
  1347. X            beep(atari);
  1348. X            exit(findAtari);
  1349. X          end;
  1350. X      end;
  1351. X  if yi > 0 then 
  1352. X    if (board[xi, yi - 1].val = other) and
  1353. X       (not board[xi, yi - 1].marked) then
  1354. X      begin
  1355. X        wipeMarks;
  1356. X        libs := 0;
  1357. X        spanGroup(other, xi, yi - 1, libs, size);
  1358. X        if libs = 1 then
  1359. X          begin
  1360. X            beep(atari);
  1361. X            exit(findAtari);
  1362. X          end;
  1363. X      end;
  1364. X  if yi < maxPoint then
  1365. X    if (board[xi, yi + 1].val = other) and
  1366. X       (not board[xi, yi + 1].marked) then
  1367. X      begin
  1368. X        wipeMarks;
  1369. X        libs := 0;
  1370. X        spanGroup(other, xi, yi + 1, libs, size);
  1371. X        if libs = 1 then
  1372. X          beep(atari);
  1373. X      end;
  1374. Xend { findAtari };
  1375. X
  1376. Xprocedure checkAtari(cm: pMRec);
  1377. Xbegin { checkAtari }
  1378. X  if cm <> treeRoot then
  1379. X    if cm^.id <> hcPlay then
  1380. X      if cm^.id <> pass then
  1381. X        begin
  1382. X          while cm^.id = remove do
  1383. X            cm := cm^.blink;
  1384. X          with cm^ do
  1385. X            findAtari(mx, my);
  1386. X      end;
  1387. Xend { checkAtari };
  1388. X
  1389. Xprocedure restoreDead;
  1390. Xvar
  1391. X  i: integer;
  1392. X  other: sType;
  1393. Xbegin { restoreDead }
  1394. X  for i := 1 to numEndDead do
  1395. X    with endDead[i] do
  1396. X      begin
  1397. X        placeStone(whoDead, dx, dy, dox, doy, mn);
  1398. X        if whoDead = white then
  1399. X          other := black
  1400. X        else
  1401. X          other := white;
  1402. X        captures[other] := captures[other] - 1;
  1403. X      end;
  1404. X  numEndDead := 0;
  1405. X  gameOver := false;
  1406. Xend { restoreDead };
  1407. X
  1408. Xprocedure backUp1;
  1409. Xvar
  1410. X  moveT: mType;
  1411. X  prevMove, tm: pMRec;
  1412. Xbegin { backUp1 }
  1413. X  if dotSX >= 0 then
  1414. X    begin
  1415. X      dotStone(dotSX, dotSY);
  1416. X      dotSX := -1;
  1417. X    end;
  1418. X  if gameOver then
  1419. X    restoreDead;
  1420. X  if curMove <> treeRoot then
  1421. X    repeat
  1422. X      with curMove^ do
  1423. X        begin
  1424. X          prevMove := blink;
  1425. X          moveT := id;
  1426. X          if id = move then
  1427. X            remStone(mx, my)
  1428. X          else if id = remove then
  1429. X            begin 
  1430. X              placeStone(who, mx, my, ox, oy, moveN);
  1431. X              if who = black then
  1432. X                captures[white] := captures[white] - 1
  1433. X              else
  1434. X                captures[black] := captures[black] - 1;
  1435. X            end
  1436. X          else if id = pass then
  1437. X            remPass
  1438. X          else { hcPlay }
  1439. X            clearBoard;
  1440. X        end;
  1441. X      curMove := prevMove;
  1442. X   until (curMove = treeRoot) or (moveT = move) or (moveT = pass); 
  1443. X   if curMove = treeRoot then
  1444. X     begin
  1445. X       koX := -1;
  1446. X       koY := -1;
  1447. X       moveNum := 0;
  1448. X     end
  1449. X   else if curMove^.id = move then
  1450. X     with curMove^ do
  1451. X       begin
  1452. X         koX := kx;
  1453. X         koY := ky;
  1454. X         moveNum := moveN;
  1455. X       end
  1456. X   else if curMove^.id = pass then
  1457. X     with curMove^ do
  1458. X       begin
  1459. X         koX := -1;
  1460. X         koY := -1;
  1461. X         moveNum := moveN;
  1462. X         showPass(who);
  1463. X       end
  1464. X   else if curMove^.id = hcPlay then
  1465. X     begin
  1466. X       koX := -1;
  1467. X       koY := -1;
  1468. X       moveNum := 1;
  1469. X     end
  1470. X   else
  1471. X     begin
  1472. X       tm := curMove^.blink;
  1473. X       while tm^.id <> move do
  1474. X         tm := tm^.blink;
  1475. X       with tm^ do
  1476. X         begin
  1477. X           koX := kx;
  1478. X           koY := ky;
  1479. X           moveNum := moveN;
  1480. X         end;
  1481. X     end;
  1482. Xend { backUp1 };
  1483. X
  1484. Xprocedure doMove(which: sType; ix, iy, pox, poy: integer);
  1485. Xvar
  1486. X  numDead: integer;
  1487. X  cm: pMRec;
  1488. Xbegin { doMove }
  1489. X  if dotSX >= 0 then
  1490. X    begin
  1491. X      dotStone(dotSX, dotSY);
  1492. X      dotSX := -1;
  1493. X    end;
  1494. X  if gameOver then
  1495. X    restoreDead;
  1496. X  curMove := newMove(curMove);
  1497. X  moveNum := moveNum + 1;
  1498. X  with curMove^ do
  1499. X    begin
  1500. X      mx := ix;
  1501. X      my := iy;
  1502. X      ox := pox;
  1503. X      oy := poy;
  1504. X      kx := koX;
  1505. X      ky := koY;
  1506. X      who := which;
  1507. X      id := move;
  1508. X      moveN := moveNum;
  1509. X    end;
  1510. X  curMove := mergeMove(curMove);
  1511. X  cm := curMove;
  1512. X  placeStone(which, ix, iy, pox, poy, moveNum);
  1513. X  remDead(ix, iy, numDead);
  1514. X  if libertyCount(ix, iy) < 1 then
  1515. X    begin
  1516. X      curMove := delBranch(curMove);
  1517. X      moveNum := moveNum + 1;
  1518. X      remStone(ix, iy);
  1519. X      beep(error);
  1520. X    end
  1521. X  else
  1522. X    begin
  1523. X      captures[which] := captures[which] + numDead;
  1524. X      if (numDead = 1) and (groupSize(ix, iy) = 1) then
  1525. X        begin
  1526. X          koX := killX;
  1527. X          koY := killY;
  1528. X        end
  1529. X      else
  1530. X        begin
  1531. X          koX := -1;
  1532. X          koY := -1;
  1533. X        end;  
  1534. X      with cm^ do
  1535. X        begin
  1536. X          kx := koX;
  1537. X          ky := koY;
  1538. X        end;
  1539. X    end;
  1540. Xend { doMove };
  1541. X
  1542. Xprocedure doPass(which: sType);
  1543. Xbegin { doPass }
  1544. X  if dotSX >= 0 then
  1545. X    begin
  1546. X      dotStone(dotSX, dotSY);
  1547. X      dotSX := -1;
  1548. X    end;
  1549. X  if gameOver then
  1550. X    restoreDead;
  1551. X  curMove := newMove(curMove);
  1552. X  moveNum := moveNum + 1;
  1553. X  with curMove^ do
  1554. X    begin
  1555. X      who := which;
  1556. X      id := pass;
  1557. X      moveN := moveNum;
  1558. X    end;
  1559. X  curMove := mergeMove(curMove);
  1560. X  showPass(which);
  1561. Xend { doPass };
  1562. X
  1563. Xprocedure doHCPlay(num: integer);
  1564. Xbegin { doHCPlay }
  1565. X  moveNum := 1;
  1566. X  curMove := newMove(treeRoot);
  1567. X  with curMove^ do
  1568. X    begin
  1569. X      who := black;
  1570. X      id := hcPlay;
  1571. X      hcNum := num;
  1572. X    end;
  1573. X  addHCStones(num);
  1574. Xend { doHCPlay };
  1575. X
  1576. Xprocedure forwardTo(m: pMRec);
  1577. Xbegin { forwardTo }
  1578. X  if dotSX >= 0 then
  1579. X    begin
  1580. X      dotStone(dotSX, dotSY);
  1581. X      dotSX := -1;
  1582. X    end;
  1583. X  curMove := m;
  1584. X  if passShowing then
  1585. X    remPass;
  1586. X  with curMove^ do
  1587. X    if id = hcPlay then
  1588. X      begin
  1589. X        addHCStones(hcNum);
  1590. X        moveNum := 1;
  1591. X      end
  1592. X    else if id = pass then
  1593. X      begin
  1594. X        moveNum := moveN;
  1595. X        koX := -1;
  1596. X        koY := -1;
  1597. X        showPass(who);
  1598. X      end
  1599. X    else
  1600. X      begin
  1601. X        moveNum := moveN;
  1602. X        placeStone(who, mx, my, ox, oy, moveNum);
  1603. X        koX := kx;
  1604. X        koY := ky;
  1605. X        while curMove^.flink <> nil do
  1606. X          if curMove^.flink^.id = remove then
  1607. X            begin
  1608. X              curMove := curMove^.flink;
  1609. X              with curMove^ do
  1610. X                remStone(mx, my);
  1611. X              if curMove^.who = white then
  1612. X                captures[black] := captures[black] + 1
  1613. X              else
  1614. X                captures[white] := captures[white] + 1
  1615. X            end
  1616. X          else
  1617. X            exit(forwardTo);
  1618. X      end;
  1619. Xend { forwardTo };
  1620. X
  1621. Xprocedure forwToBr;
  1622. Xvar
  1623. X  atBr: boolean;
  1624. Xbegin { forwToBr }
  1625. X  if dotSX >= 0 then
  1626. X    begin
  1627. X      dotStone(dotSX, dotSY);
  1628. X      dotSX := -1;
  1629. X    end;
  1630. X  atBr := false;
  1631. X  repeat
  1632. X    if curMove^.flink = nil then
  1633. X      atBr := true
  1634. X    else if curMove^.flink^.slink <> nil then
  1635. X      atBr := true
  1636. X    else
  1637. X      forwardTo(curMove^.flink);
  1638. X  until atBr;
  1639. Xend { forwToBr };
  1640. X
  1641. Xprocedure backToBr;
  1642. Xvar
  1643. X  na: integer;
  1644. X  tm: pMRec;
  1645. X  endLoop: boolean;
  1646. Xbegin { backToBr }
  1647. X  if dotSX >= 0 then
  1648. X    begin
  1649. X      dotStone(dotSX, dotSY);
  1650. X      dotSX := -1;
  1651. X    end;
  1652. X  if curMove <> treeRoot then
  1653. X    begin
  1654. X      if not hasAlts(curMove) then
  1655. X        repeat
  1656. X          backUp1;
  1657. X          if curMove = treeRoot then
  1658. X            endLoop := true
  1659. X          else
  1660. X            endLoop := hasAlts(curMove);
  1661. X        until endLoop;
  1662. X      if curMove <> treeRoot then
  1663. X        backUp1;
  1664. X    end
  1665. X  else
  1666. X    beep(error);
  1667. Xend { backToBr };
  1668. X
  1669. Xfunction atBranch(cm: pMRec): boolean;
  1670. Xbegin { atBranch }
  1671. X  if cm^.flink <> nil then
  1672. X    atBranch := cm^.flink^.slink <> nil
  1673. X  else
  1674. X    atBranch := false;
  1675. Xend { atBranch };
  1676. X
  1677. Xfunction atLeaf(cm: pMRec): boolean;
  1678. Xbegin { atLeaf }
  1679. X  atLeaf := cm^.flink = nil;
  1680. Xend { atLeaf };
  1681. X
  1682. Xprocedure showAlts;
  1683. Xvar
  1684. X  tm: pMRec;
  1685. Xbegin { showAlts }
  1686. X  setMenuCursor;
  1687. X  tm := curMove^.flink;
  1688. X  passIsAlt := false;
  1689. X  while tm <> nil do
  1690. X    begin
  1691. X      with tm^ do
  1692. X        begin
  1693. X          if id = move then
  1694. X            placeAlt(who, mx, my, ox, oy)
  1695. X          else if id = pass then
  1696. X            begin
  1697. X              SChrFunc(ord(rNot));
  1698. X              showPass(who);
  1699. X              SChrFunc(ord(rRpl));
  1700. X              passIsAlt := true;
  1701. X            end;
  1702. X          tm := tm^.slink;
  1703. X        end;
  1704. X    end;
  1705. Xend { showAlts };
  1706. X
  1707. Xprocedure remAlts;
  1708. Xvar
  1709. X  tm: pMRec;
  1710. Xbegin { remAlts }
  1711. X  tm := curMove^.flink;
  1712. X  while tm <> nil do
  1713. X    begin
  1714. X      with tm^ do
  1715. X        begin
  1716. X          if id = move then
  1717. X            remStone(mx, my)
  1718. X          else if id = pass then
  1719. X            remPass;
  1720. X          tm := tm^.slink;
  1721. X        end;
  1722. X    end;
  1723. Xend { remAlts };
  1724. X
  1725. Xprocedure selAlt(lx, ly: integer);
  1726. Xbegin { selAlt }
  1727. X  remAlts;
  1728. X  curMove := curMove^.flink;
  1729. X  repeat
  1730. X    while curMove^.id <> move do
  1731. X      curMove := curMove^.slink;
  1732. X    if (curMove^.mx = lx) and (curMove^.my = ly) then
  1733. X      begin
  1734. X        forwardTo(curMove);
  1735. X        exit(selAlt);
  1736. X      end
  1737. X    else
  1738. X      curMove := curMove^.slink;
  1739. X  until false;
  1740. Xend { selAlt };
  1741. X
  1742. Xprocedure selPass;
  1743. Xbegin { selPass }
  1744. X  remAlts;
  1745. X  curMove := curMove^.flink;
  1746. X  while curMove^.id <> pass do
  1747. X    curMove := curMove^.slink;
  1748. X  forwardTo(curMove);
  1749. Xend { selPass };
  1750. X
  1751. Xprocedure switchBranch(bm: pMRec);
  1752. Xvar
  1753. X  tm: pMRec;
  1754. Xbegin { switchBranch }
  1755. X  if dotSX >= 0 then
  1756. X    begin
  1757. X      dotStone(dotSX, dotSY);
  1758. X      dotSX := -1;
  1759. X    end;
  1760. X  if gameOver then
  1761. X    restoreDead;
  1762. X  wipeTreeMarks;
  1763. X  tm := bm;
  1764. X  while tm <> treeRoot do
  1765. X    begin
  1766. X      tm^.mark := true;
  1767. X      tm := tm^.blink;
  1768. X    end;
  1769. X  treeRoot^.mark := true;
  1770. X  while not curMove^.mark do
  1771. X    backup1;
  1772. X  while curMove <> bm do
  1773. X    begin
  1774. X      tm := curMove^.flink;
  1775. X      while not tm^.mark do
  1776. X        tm := tm^.slink;
  1777. X      forwardTo(tm);
  1778. X    end;
  1779. Xend { switchBranch };
  1780. X
  1781. Xfunction stepTagPossible: boolean;
  1782. Xbegin { stepTagPossible }
  1783. X  if treeRoot^.lastTag = nil then
  1784. X    stepTagPossible := false
  1785. X  else if stepTag = nil then
  1786. X    stepTagPossible := true
  1787. X  else if curMove = treeRoot then
  1788. X    stepTagPossible := true
  1789. X  else if curMove^.tag = stepTag then
  1790. X    stepTagPossible := false
  1791. X  else
  1792. X    stepTagPossible := true;
  1793. Xend { stepTagPossible };
  1794. X
  1795. Xprocedure doStepTag;
  1796. Xvar
  1797. X  tm: pMRec;
  1798. Xbegin { doStepTag }
  1799. X  if stepTag = nil then
  1800. X    exit(doStepTag);
  1801. X  if dotSX >= 0 then
  1802. X    begin
  1803. X      dotStone(dotSX, dotSY);
  1804. X      dotSX := -1;
  1805. X    end;
  1806. X  if gameOver then
  1807. X    restoreDead;
  1808. X  tm := stepTag^.mPtr;
  1809. X  if curMove = tm then
  1810. X    exit(doStepTag);
  1811. X  wipeTreeMarks;
  1812. X  while tm <> treeRoot do
  1813. X    begin
  1814. X      tm^.mark := true;
  1815. X      tm := tm^.blink;
  1816. X    end;
  1817. X  treeRoot^.mark := true;
  1818. X  if not curMove^.mark then
  1819. X    begin
  1820. X      prompt('Backed up to proper branch');
  1821. X      repeat
  1822. X        backup1;
  1823. X      until curMove^.mark;
  1824. X    end
  1825. X  else 
  1826. X    begin
  1827. X      tm := curMove^.flink;
  1828. X      while not tm^.mark do
  1829. X        tm := tm^.slink;
  1830. X      forwardTo(tm);
  1831. X    end;
  1832. Xend { doStepTag };
  1833. X
  1834. Xprocedure scoreGame(var ws, bs: integer);
  1835. Xvar
  1836. X  i, j, size: integer;
  1837. X  bSeen, wSeen: boolean;
  1838. X
  1839. X  procedure spanEmpties(bx, by: integer);
  1840. X  begin { spanEmpties }
  1841. X    if (bx >= 0) and (bx <= maxPoint) and
  1842. X       (by >= 0) and (by <= maxPoint) then
  1843. X      begin
  1844. X        if board[bx, by].val = white then
  1845. X          wSeen := true
  1846. X        else if board[bx, by].val = black then
  1847. X          bSeen := true
  1848. X        else if not board[bx, by].marked then
  1849. X          begin
  1850. X            board[bx, by].marked := true;
  1851. X            size := size + 1;
  1852. X            spanEmpties(bx - 1, by);
  1853. X            spanEmpties(bx + 1, by);
  1854. X            spanEmpties(bx, by - 1);
  1855. X            spanEmpties(bx, by + 1);
  1856. X          end;
  1857. X      end;
  1858. X  end { spanEmpties };
  1859. X
  1860. Xbegin { scoreGame }
  1861. X  ws := 0;
  1862. X  bs := 0;
  1863. X  wipeMarks;
  1864. X  for j := 0 to maxPoint do
  1865. X    for i := 0 to maxPoint do
  1866. X      if (not board[i, j].marked) and
  1867. X         (board[i, j].val = empty) then
  1868. X        begin
  1869. X          bSeen := false;
  1870. X          wSeen := false;
  1871. X          size := 0;
  1872. X          spanEmpties(i, j);
  1873. X          if bSeen and not wSeen then
  1874. X            bs := bs + size
  1875. X          else if wSeen and not bSeen then
  1876. X            ws := ws + size;
  1877. X        end;
  1878. Xend { scoreGame };
  1879. X
  1880. Xprocedure putEnd;
  1881. Xbegin { putEnd }
  1882. X  if not gameOver then
  1883. X    begin
  1884. X      gameOver := true;
  1885. X      numEndDead := 0;
  1886. X    end;
  1887. Xend { putEnd };
  1888. X
  1889. Xprocedure delGroup(bx, by: integer);
  1890. Xvar
  1891. X  sto, other: sType;
  1892. X  size: integer;
  1893. X
  1894. X  procedure dumpDead(bx, by: integer);
  1895. X  begin { dumpDead }
  1896. X    if (bx >= 0) and (bx <= maxPoint) and
  1897. X       (by >= 0) and (by <= maxPoint) then
  1898. X      if board[bx, by].val = sto then
  1899. X        begin
  1900. X          remStone(bx, by);
  1901. X          numEndDead := numEndDead + 1;
  1902. X          with endDead[numEndDead] do
  1903. X            begin
  1904. X              dx := bx;
  1905. X              dy := by;
  1906. X              with board[bx, by] do
  1907. X                begin
  1908. X                  dox := xOfs;
  1909. X                  doy := yOfs;
  1910. X                  mn := mNum;
  1911. X                end;
  1912. X              whoDead := sto;
  1913. X            end;
  1914. X          size := size + 1;
  1915. X          dumpDead(bx - 1, by);
  1916. X          dumpDead(bx + 1, by);
  1917. X          dumpDead(bx, by - 1);
  1918. X          dumpDead(bx, by + 1);
  1919. X        end;
  1920. X  end { dumpDead };
  1921. X
  1922. Xbegin { delGroup }
  1923. X  sto := board[bx, by].val;
  1924. X  size := 0;
  1925. X  dumpDead(bx, by);
  1926. X  if sto = white then
  1927. X    other := black
  1928. X  else
  1929. X    other := white;
  1930. X  captures[other] := captures[other] + size;
  1931. Xend { delGroup };
  1932. X
  1933. Xprocedure dotLast;
  1934. Xvar
  1935. X  tm: pMRec;
  1936. Xbegin { dotLast }
  1937. X  if numbEnabled then
  1938. X    exit(dotLast);
  1939. X  if dotSX >= 0 then
  1940. X    dotStone(dotSX, dotSY);
  1941. X  dotSX := -1;
  1942. X  tm := curMove;
  1943. X  while tm <> treeRoot do
  1944. X    if tm^.id = pass then
  1945. X      exit(dotLast)
  1946. X    else if tm^.id = move then
  1947. X      with tm^ do
  1948. X        begin
  1949. X          dotSX := mx;
  1950. X          dotSY := my;
  1951. X          dotStone(mx, my);
  1952. X          exit(dotLast);
  1953. X        end
  1954. X    else
  1955. X      tm := tm^.blink;
  1956. Xend { dotLast };
  1957. X
  1958. Xprocedure initGoMgr;
  1959. Xbegin { initGoMgr }
  1960. X  moveNum := 0;
  1961. X  curMove := treeRoot;
  1962. X  gameOver := false;
  1963. X  numEndDead := 0;
  1964. X  dotSX := -1;
  1965. X  dotSY := -1;
  1966. X  passShowing := false;
  1967. Xend. { initGoMgr }
  1968. END_OF_goMgr.pas
  1969. if test 20985 -ne `wc -c <goMgr.pas`; then
  1970.     echo shar: \"goMgr.pas\" unpacked with wrong size!
  1971. fi
  1972. # end of overwriting check
  1973. fi
  1974. echo shar: End of archive 4 \(of 5\).
  1975. cp /dev/null ark4isdone
  1976. MISSING=""
  1977. for I in 1 2 3 4 5 ; do
  1978.     if test ! -f ark${I}isdone ; then
  1979.     MISSING="${MISSING} ${I}"
  1980.     fi
  1981. done
  1982. if test "${MISSING}" = "" ; then
  1983.     echo You have unpacked all 5 archives.
  1984.     rm -f ark[1-9]isdone
  1985. else
  1986.     echo You still need to unpack the following archives:
  1987.     echo "        " ${MISSING}
  1988. fi
  1989. ##  End of shell archive.
  1990. exit 0
  1991.